home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / fgrep.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  5KB  |  286 lines

  1. /* fgrep - fast grep            Author: Jan Christiaan van Winkel */
  2.  
  3. #include <sys/types.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6.  
  7. int argc;
  8. char **argv;
  9. int stringlen, offset, boundary;
  10. int i, j, k, count, linum;
  11. char stringarea[1024];
  12. int strptr;
  13. int strcount;
  14. unsigned char tbl[32][256];
  15. int lengths[32];
  16. char *tststring[32];
  17. char string[512];
  18. char tmpstring[512];
  19. int vflag, cflag, nofname, hadone, lflag, nflag, sflag, hflag, eflag, fflag;
  20. int fp;
  21.  
  22. main(oargc, oargv)
  23. int oargc;
  24. char *oargv[];
  25.  
  26. {
  27.   int find();
  28.   void exparg();
  29.   void getargs();
  30.   void gotone();
  31.  
  32.   argc = oargc;
  33.   argv = oargv;
  34.   getargs();
  35.  
  36.   fp = 0;
  37.   if (i >= argc - 2 || hflag)    /* stdin, 1 file, hflag */
  38.     nofname = 1;
  39.  
  40.   do {
  41.     if (i < argc && (fp = open(argv[i], O_RDONLY)) < 0) {
  42.         fprintf(stderr, "%s: can't open %s\n", argv[0], argv[i]);
  43.         continue;
  44.     }
  45.     count = 0;
  46.     linum = 0;
  47.  
  48.     while ((stringlen = getlin(fp, string, 512)) != EOF) {
  49.         linum++;
  50.         for (j = 0; j < strcount; j++) {
  51.             if (find(tststring[j], tbl[j], lengths[j]) != vflag) {
  52.                 gotone();
  53.                 break;
  54.             }
  55.         }
  56.         if (lflag && count) break;
  57.     }
  58.     close(fp);
  59.  
  60.     if (cflag) {
  61.         printf("%s: %d times\n", argv[i], count);
  62.     }
  63.     if (lflag && count > 0) {
  64.         printf("%s\n", argv[i]);
  65.     }
  66.   } while (++i < argc);
  67.  
  68.   fflush(stdout);
  69.   if (hadone)
  70.     exit(0);
  71.   else
  72.     exit(1);
  73. }
  74.  
  75. void getargs()
  76. {
  77.   int tmp;
  78.   void maktbl();
  79.   for (i = 1; i < argc && argv[i][0] == '-'; i++) {
  80.     switch (argv[i][1]) {
  81.         case 'e':
  82.         eflag = 1;
  83.         if (fflag) {
  84.             fprintf(stderr, "%s: can't have -e and -f at the same time\n", argv[0]);
  85.             exit(2);
  86.         }
  87.         if (i < argc - 1) {
  88.             i++;
  89.             tststring[0] = argv[i];
  90.             strcount = 1;
  91.         } else {
  92.             fprintf(stderr, "%s: not enough arguments\n");
  93.             exit(2);
  94.         }
  95.         break;
  96.         case 'v':    vflag = 1;    break;
  97.         case 'c':    cflag = 1;    break;
  98.         case 'l':    lflag = 1;    break;
  99.         case 's':    sflag = 1;    break;
  100.         case 'h':    hflag = 1;    break;
  101.         case 'n':    nflag = 1;    break;
  102.         case 'f':
  103.         fflag = 1;
  104.         if (eflag) {
  105.             fprintf(stderr, 
  106.                "%s: can't have -e and -f at the same time\n", argv[0]);
  107.             exit(2);
  108.         }
  109.         if (i >= argc - 1) {
  110.             fprintf(stderr, "%s: not enough arguments\n");
  111.             exit(2);
  112.         } else {
  113.             i++;
  114.             if ((fp = open(argv[i], O_RDONLY)) < 0) {
  115.                 fprintf(stderr, 
  116.                       "%s: can't open %s\n", argv[0], argv[i]);
  117.                 exit(2);
  118.             }
  119.             strcount = 0;
  120.             while ((tmp = getlin(fp, &stringarea[strptr], 128)) != EOF) {
  121.                 tststring[strcount++] = &stringarea[strptr];
  122.                 strptr = strptr + tmp + 1;
  123.                 if (strptr >= 1024 - 128 || strcount == 32) {
  124.                     fprintf(stderr, "%s: not enough room\n", argv[0]);
  125.                     exit(2);
  126.                 }
  127.             }
  128.             close(fp);
  129.         }
  130.         break;
  131.         default:
  132.         fprintf(stderr, "%s: invalid command line option\n", argv[0]);
  133.         exit(2);
  134.         break;
  135.     }
  136.     if (cflag && lflag) {
  137.         fprintf(stderr, "%s: cannot have -l and -c at the same time\n", argv[0]);
  138.         exit(2);
  139.     }
  140.   }
  141.  
  142.   if (!eflag && !fflag) {
  143.     if (i < argc) {
  144.         tststring[0] = argv[i++];
  145.         strcount = 1;
  146.     } else {
  147.         fprintf(stderr, "%s: no search string.\n", argv[0]);
  148.         exit(2);
  149.     }
  150.   }
  151.   for (j = 0; j < strcount; j++) {
  152.     if (tststring[j][0] == '"') {
  153.         count = strlen(tststring[j]);
  154.         movmem(&tststring[j][1], tststring[j], count - 2);
  155.         tststring[j][count - 2] = '\0';
  156.     }
  157.     maktbl(tststring[j], tbl[j], &lengths[j]);
  158.   }
  159. }
  160.  
  161.  
  162. movmem(src, dst, len)
  163. char *src, *dst;
  164. int len;
  165. {
  166.   while (len--) *dst++ = *src++;
  167. }
  168.  
  169. setmem(mem, len, filler)
  170. char *mem;
  171. int len;
  172. char filler;
  173. {
  174.   while (len--) *mem++ = filler;
  175. }
  176.  
  177.  
  178. int find(findword, table, wordlen)
  179. unsigned char *findword;
  180. unsigned char *table;
  181. int wordlen;
  182. {
  183.   auto int lastletter, tmp;
  184.  
  185.   boundary = stringlen - wordlen;
  186.   lastletter = wordlen - 1;
  187.   offset = 0;
  188.   while (offset <= boundary) {
  189.     tmp = table[string[offset + lastletter]];
  190.     if (tmp) {
  191.         offset += tmp;
  192.     } else {
  193.         for (k = lastletter - 1; k >= 0; k--) {
  194.             if ((string[k + offset]) != findword[k]) {
  195.                 offset++;
  196.                 break;
  197.             }
  198.         }
  199.         if (k < 0) return(1);
  200.     }
  201.   }
  202.   return(0);
  203. }
  204.  
  205.  
  206. void maktbl(findword, table, wordlen)
  207. unsigned char *findword;
  208. unsigned char *table;
  209. int *wordlen;
  210. {
  211.  
  212.   auto int i, len;
  213.  
  214.   *wordlen = len = strlen(findword);
  215.   setmem(table, 256, len);
  216.   for (i = 0; i < len; i++) table[findword[i]] = len - i - 1;
  217. }
  218.  
  219.  
  220. void gotone()
  221. {
  222.   hadone = 1;
  223.  
  224.   if (cflag || lflag || sflag) {
  225.     count++;
  226.     return;
  227.   }
  228.   if (!nofname) printf("%s:", argv[i]);
  229.  
  230.   if (nflag) printf("%d:", linum);
  231.  
  232.   printf("%s\n", string);
  233. }
  234.  
  235.  
  236. int getlin(infile, buf, maxlen)
  237. int infile;
  238. char *buf;
  239. int maxlen;
  240. {
  241.   static char mybuf[2048];
  242.   static char *low;
  243.   static char *high;
  244.  
  245.   auto int status;
  246.   auto char *p = buf;
  247.   auto int endline;
  248.  
  249.   *p = '\0';
  250.   maxlen--;
  251.   while (1) {
  252.     endline = 0;
  253.     while (low < high && !endline) {
  254.         if (p >= &buf[maxlen]) {    /* overflow, skip all
  255.                          * until \n */
  256.             while (low < high && *low != '\n') low++;
  257.             endline = (*low == '\n');
  258.         } else
  259.             endline = ((*p++ = *low++) == '\n');
  260.  
  261.     }            /* exhausted buffer or found \n */
  262.  
  263.     /* Don't continue if \n found */
  264.     if (endline) {
  265.         *(p - 1) = '\0';
  266.         return(p - buf - 1);
  267.     }
  268.     status = read(infile, mybuf, 2048);
  269.     if (status <= 0) break;
  270.  
  271.     low = mybuf;
  272.     high = &mybuf[status];
  273.  
  274.   }
  275.  
  276.   /* Empty line or a bit filled ? */
  277.   *p = '\0';
  278.   if (status < 0) {
  279.     perror("read error");
  280.     return(EOF);
  281.   }
  282.   if (p - buf) return(p - buf);
  283.   return(EOF);
  284.  
  285. }                /* of getlin() */
  286.